﻿using System;
using ValidationFramework.Configuration.Reflection;

namespace ValidationFramework.Specifications
{
	/// <summary>
	/// Specifies that a <see cref="EnumConversionRule"/> should be applied to the program element.
	/// </summary>
	/// <seealso cref="EnumConversionRule"/>
	/// <example>
	/// <code source="Examples\ExampleLibraryCSharp\Specifications\EnumConversionRuleAttributeExample.cs" lang="cs"/>
	/// <code source="Examples\ExampleLibraryVB\Specifications\EnumConversionRuleAttributeExample.vb" lang="vbnet"/>
	/// </example>
#if (!SILVERLIGHT)
	[Serializable]
#endif
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
	public sealed class IsConvertableToEnumAttribute : RuleAttribute
	{

		// --- Constructors

		/// <param name="enumTypeName">A string representing the <see cref="Enum"/> <see cref="Type"/> to convert to.</param>
		public IsConvertableToEnumAttribute(string enumTypeName)
		{
			EnumType = Type.GetType(enumTypeName);
		}

		/// <param name="enumType">The <see cref="Enum"/> <see cref="Type"/> to convert to.</param>
		public IsConvertableToEnumAttribute(Type enumType)
		{
			EnumType = enumType;
		}


		// --- Properties

		/// <summary>
		/// Gets or sets the enum <see cref="Type"/>.
		/// </summary>
		public Type EnumType
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets or sets weather to ignore case. 
		/// </summary>
		/// <remarks>
		/// Only applicable if the property type is string.
		/// </remarks>
		public bool IgnoreCase
		{
			get;
			set;
		}



		// --- Methods

		public override ISpecification CreateSpecification(ICachedReflectionInfo descriptor)
		{
			return new IsConvertableToEnumSpec(EnumType)
			{
				IgnoreCase = IgnoreCase
			};
		}
	}
}